package top.kangyaocoding.mall.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import top.kangyaocoding.mall.IOrderDao;
import top.kangyaocoding.mall.IOrderService;
import top.kangyaocoding.mall.constants.Constants;
import top.kangyaocoding.mall.po.PayOrder;
import top.kangyaocoding.mall.req.ShopCartReq;
import top.kangyaocoding.mall.res.PayOrderRes;
import top.kangyaocoding.mall.rpc.ProductRPC;
import top.kangyaocoding.mall.vo.ProductVO;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 描述: 订单服务实现类
 *
 * @author K·Herbert
 * @since 2024-12-25 下午4:30
 */
@Slf4j
@Service
public class OrderServiceImpl implements IOrderService {

    @Value("${alipay.notify_url}")
    private String notifyUrl;
    @Value("${alipay.return_url}")
    private String returnUrl;

    @Resource
    private IOrderDao orderDao;
    @Resource
    private ProductRPC productRPC;
    @Resource
    private AlipayClient alipayClient;

    @Override
    public PayOrderRes createOrder(ShopCartReq shopCartReq) {
        // 查询用户是否存在未支付的订单或掉单
        String userId = shopCartReq.getUserId();
        String productId = shopCartReq.getProductId();

        PayOrder payOrderReq = PayOrder.builder()
                .userId(userId)
                .productId(productId)
                .build();
        PayOrder unpaidOrder = orderDao.queryUnpaidOrder(payOrderReq);

        // 如果有未支付的订单，则直接返回。否则判断是否掉单
        if (null != unpaidOrder && unpaidOrder.getStatus().equals(Constants.OrderStatusEnum.PAY_WAIT.getCode())) {
            log.info("用户{}存在未支付的订单，商品号：{} 订单号：{}", userId, productId, unpaidOrder.getOrderId());
            return PayOrderRes.builder()
                    .orderId(unpaidOrder.getOrderId())
                    .payUrl(unpaidOrder.getPayUrl())
                    .build();
        } else if (null != unpaidOrder && unpaidOrder.getStatus().equals(Constants.OrderStatusEnum.CREATE.getCode())) {
            // 掉单
            log.info("创建订单-存在，存在未创建支付单订单，创建支付单开始 用户Id:{} 商品Id:{} 订单Id:{}", userId, productId, unpaidOrder.getOrderId());
            PayOrder payOrder = doPrepayOrder(unpaidOrder.getProductId(), unpaidOrder.getProductName(), unpaidOrder.getOrderId(), unpaidOrder.getTotalAmount());
            return PayOrderRes.builder()
                    .orderId(payOrder.getOrderId())
                    .payUrl(payOrder.getPayUrl())
                    .build();
        }

        // 查询商品 && 创建订单
        ProductVO productVO = productRPC.queryProductByProductId(productId);
        String orderId = RandomStringUtils.randomNumeric(16);
        log.info("创建订单-不存在，创建支付单开始 用户Id:{} 商品Id:{} 订单Id:{}", userId, productId, orderId);
        orderDao.insert(PayOrder.builder()
                .userId(userId)
                .productId(productId)
                .productName(productVO.getProductName())
                .orderId(orderId)
                .orderTime(new Date())
                .totalAmount(productVO.getPrice())
                .status(Constants.OrderStatusEnum.CREATE.getCode())
                .build());

        // 创建支付订单
        PayOrder payOrder = doPrepayOrder(productVO.getProductId(), productVO.getProductName(), orderId, productVO.getPrice());


        return PayOrderRes.builder()
                .orderId(orderId)
                .payUrl(payOrder.getPayUrl())
                .build();
    }

    private PayOrder doPrepayOrder(String productId, String productName, String orderId, BigDecimal totalAmount) {
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
        request.setNotifyUrl(notifyUrl);
        request.setReturnUrl(returnUrl);

        // 构建bizContent
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderId);
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        bizContent.put("total_amount", totalAmount);
        bizContent.put("subject", productName);
        request.setBizContent(bizContent.toJSONString());

        try {
            String form = alipayClient.pageExecute(request).getBody();
            // 构建返回
            PayOrder payOrder = PayOrder.builder()
                    .orderId(orderId)
                    .payUrl(form)
                    .status(Constants.OrderStatusEnum.PAY_WAIT.getCode())
                    .build();

            orderDao.updateOrderPayInfo(payOrder);

            return payOrder;

        } catch (AlipayApiException e) {
            log.error("创建支付宝支付订单异常", e);
            throw new RuntimeException("创建支付宝支付订单异常");
        }
    }
}
